package com.iwdnb.gkgz.application.strategy;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import cn.hutool.core.date.DateUtil;
import com.iwdnb.gkgz.application.model.request.AddStrategyTradeStockDataRequest;
import com.iwdnb.gkgz.common.enums.RangeTypeEnums;
import com.iwdnb.gkgz.common.model.dto.StockDayData;
import com.iwdnb.gkgz.common.model.dto.StockRangeDTO;
import com.iwdnb.gkgz.common.model.dto.StrategyTradeDTO;
import com.iwdnb.gkgz.common.utils.BigDecimalUtils;
import com.iwdnb.gkgz.common.utils.StockRangeUtils;
import com.iwdnb.gkgz.common.utils.StockUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 非买入策略，是查看股票暴涨波段
 */
@Service
@Slf4j
public class BoomStockBackValidateService extends CommmonStockBackValidateService {

    private static final String STATEGY_CODE = "boom";

    @Override
    public List<StrategyTradeDTO> queryBackValidateDateList(String code, String strategy,
        List<StockDayData> stockDayDataList, AddStrategyTradeStockDataRequest request) {
        List<String> dateList = new ArrayList<>();
        List<StrategyTradeDTO> strategyTradeDTOList = new ArrayList<>();
        List<StockRangeDTO> stockRangeDTOList = StockRangeUtils.calculateStockRange(stockDayDataList);
        for (StockRangeDTO stockRange : stockRangeDTOList) {
            if (RangeTypeEnums.DOWN.equalsCode(stockRange.getRangeType())) {
                continue;
            }
            if (BigDecimalUtils.isLe(stockRange.getRate(), fifty)) {
                continue;
            }
            Date d = DateUtil.parseDate(stockRange.getBeginDate());
            int year = DateUtil.year(d);
            if(year<2017){
                continue;
            }
            //找到快速上涨的波段区间
            StockRangeDTO fastUpRange = caculateFastUpRange(stockRange, stockDayDataList);
            if (Objects.isNull(fastUpRange)) {
                continue;
            }
            StockDayData data = StockUtils.getStockDayData(stockDayDataList, fastUpRange.getBeginDate());
            String date = data.getDate();
            if (!dateList.contains(date)) {
                dateList.add(date);
                StrategyTradeDTO strategyTradeDTO = new StrategyTradeDTO();
                strategyTradeDTO.setCode(code);
                strategyTradeDTO.setUuid(STATEGY_CODE);
                strategyTradeDTO.setBuyDate(DateUtil.parseDate(date));
                strategyTradeDTO.setBuyPrice(data.getClosePrice());
                strategyTradeDTO.setHoldDay(fastUpRange.getHoldDay());
                strategyTradeDTO.setSellDate(DateUtil.parseDate(fastUpRange.getEndDate()));
                strategyTradeDTO.setSellPrice(fastUpRange.getHighPrice());
                strategyTradeDTO.setProfitRate(fastUpRange.getRate());
                strategyTradeDTO.setRangeMaxPrice(fastUpRange.getHighPrice());
                strategyTradeDTO.setRangeMaxRate(fastUpRange.getRate());
                strategyTradeDTO.setStrategyDescription(fastUpRange.getRate().toPlainString());
                strategyTradeDTO.setStatus("sell");
                strategyTradeDTO.setWinFlag("y");
                strategyTradeDTOList.add(strategyTradeDTO);

            }
        }
        return strategyTradeDTOList;
    }

    /**
     * 找到快速上涨的波段区间
     *
     * @param stockRange
     * @param stockDayDataList
     * @return
     */
    private StockRangeDTO caculateFastUpRange(StockRangeDTO stockRange, List<StockDayData> stockDayDataList) {
        stockDayDataList = StockUtils.getStockDayDataListByDateRange(stockDayDataList, stockRange.getBeginDate(),
            stockRange.getEndDate());
        StockDayData filterBeginData = null;
        StockDayData filterEndData = null;
        int holdDay = 0;
        for (int i = 0; i < stockDayDataList.size(); i++) {
            StockDayData data = stockDayDataList.get(i);
            for (int j = i + 10; j < stockDayDataList.size(); j++) {
                StockDayData endData = stockDayDataList.get(j);
                int dateSize = j - i;
                if (dateSize > 20) {
                    continue;
                }
                BigDecimal dateRange = BigDecimalUtils.subStractAndDividePrecent(endData.getClosePrice(),
                    data.getClosePrice());
                BigDecimal dayRate = BigDecimalUtils.divide(dateRange, new BigDecimal(dateSize));
                if (BigDecimalUtils.isGe(dayRate, three) && dateSize > holdDay) {
                    filterBeginData = data;
                    filterEndData = endData;
                    holdDay = dateSize;
                }
            }
        }
        if (Objects.nonNull(filterBeginData)) {
            stockRange.setBeginDate(filterBeginData.getDate());
            stockRange.setEndDate(filterEndData.getDate());
            stockRange.setLowPrice(filterBeginData.getClosePrice());
            stockRange.setHighPrice(filterEndData.getClosePrice());
            stockRange.setRate(
                BigDecimalUtils.subStractAndDividePrecent(stockRange.getHighPrice(), stockRange.getLowPrice()));
            stockRange.setHoldDay(holdDay);
            return stockRange;
        }
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void doBackValidate(String code, String strategy, List<StockDayData> stockDayDataList,
        List<StrategyTradeDTO> strategyTradeDTOList) {

    }

}
